/*
  File:    ImprovedMath.cpp
  Purpose: To provide some additional math functions and 
           improved performance and accuracy for powers, 
		   rounding, and min/max. Inlining is used to 
		   further improve performance. 

  Contact: Paul Macklin
           pmacklin@math.uci.edu
		   http://math.uci.edu/~pmacklin
*/

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>

#include "random.h"
#include "ImprovedMath.h"

using namespace std;

int ImprovedRound( double input )
{
 double eps = 1e-16;
 int FloorInteger = (int) floor(input);
 
 double DecimalPart = input - FloorInteger;
 if( DecimalPart < 0.5 )
 { return FloorInteger; }
 if( DecimalPart > 0.5 )
 { return FloorInteger+1; }

 extern float (*UniformRandom)(void);
 if( !UniformRandom )
 { UniformRandom = GreatUniformRandom; SeedRandom(); }
 
 float RandomNumber = UniformRandom();
 if( RandomNumber >= 0.5 )
 { return FloorInteger+1; }
 return FloorInteger; 
}

double IntPow( double base, int power )
{
 if( power < 0 )
 { base = 1.0 / base; power *= -1; }

 int i=0;
 double Output = 1.0;
 while( i < power )
 { Output *= base; i++; }
 return Output;
}

int factorial( int power )
{
 int output = 1;
 int i;
 if( power <= 0 )
 { return 1; }
 for( i=1 ; i <= power ;i++)
 {
  output *= i;
 }
 return output;
}

double GammaFunction( int in )
{
 return factorial( in-1 );
}
